package easier.exoplayer;

import android.net.Uri;
import android.view.View;
import android.view.View.OnClickListener;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Player.Listener;
import com.google.android.exoplayer2.Player.State;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.source.ProgressiveMediaSource.Factory;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;

/**
 * 简化处理exo-player
 * 1.创建播放器{@link #createPlayer()}
 * 2.设置数据源{@link #setMediaSourceFromUri(Uri)}
 * 3.播放{@link #play()}
 * 4.暂停{@link #pause()},暂停之后可以回到第3步继续播放
 * 5.停止{@link #stop()},停止之后可以回到第2,3步继续播放
 * 6.释放播放器资源{@link #releasePlayer()},释放资源之后可以回到第1,2,3步继续播放新数据
 */
public class ExoPlayerEasier {

    /**
     * view
     */
    private final @NonNull PlayerView playerView;

    public ExoPlayerEasier( @NonNull PlayerView playerView ) {

        this.playerView = playerView;
    }

    /**
     * 创建播放器,必须先创建播放器,才能播放
     */
    public void createPlayer() {

        SimpleExoPlayer exoPlayer = new SimpleExoPlayer.Builder( playerView.getContext() ).build();
        playerView.setPlayer( exoPlayer );
    }

    /**
     * 释放播放器,释放之后{@link #getPlayer()}将返回null,再次播放只能使用{@link #createPlayer()}创建新的播放器
     */
    public void releasePlayer() {

        Player player = playerView.getPlayer();
        if ( player != null ) {
            player.release();
            playerView.setPlayer( null );
        }
    }

    /**
     * @param uri 设置播放数据源,设置之后将准备播放该数据
     */
    public void setMediaSourceFromUri( Uri uri ) {

        Player player = playerView.getPlayer();
        if ( player instanceof SimpleExoPlayer ) {
            DefaultHttpDataSource.Factory sourceFactory = new DefaultHttpDataSource.Factory();
            sourceFactory.setUserAgent( "user-agent" );
            ProgressiveMediaSource mediaSource = new Factory( sourceFactory ).createMediaSource( MediaItem.fromUri( uri ) );
            ((SimpleExoPlayer) player).setMediaSource( mediaSource );
            player.prepare();
        }
    }

    /**
     * 播放数据源数据,必须拥有播放器{@link #createPlayer()}和数据源之后才能播放{@link #setMediaSourceFromUri(Uri)}
     * 可以暂停播放{@link #pause()},暂停之后使用该方法恢复播放
     * 停止播放之后{@link #stop()},必须重新设置数据源{@link #setMediaSourceFromUri(Uri)}才能继续播放
     */
    public void play() {

        Player player = playerView.getPlayer();
        if ( player == null ) {
            return;
        }

        if ( player.isPlaying() ) {
            return;
        }

        int playbackState = player.getPlaybackState();
        if ( playbackState == Player.STATE_IDLE ) {
            return;
        }

        if ( playbackState == Player.STATE_ENDED ) {
            player.seekTo( 0 );
        }

        player.setPlayWhenReady( true );
    }

    /**
     * 停止播放之后,播放器处于闲置状态,可以通过该方法判断返回值为true,需要设置数据源才能继续播放
     *
     * @return true:播放器处于闲置状态{@link Player#STATE_IDLE}
     */
    public boolean playerIsIdleState() {

        Player player = playerView.getPlayer();
        if ( player != null ) {
            return player.getPlaybackState() == Player.STATE_IDLE;
        }
        return false;
    }

    /**
     * @return true:正在播放状态
     */
    public boolean isPlaying() {

        if ( playerView.getPlayer() != null ) {
            return playerView.getPlayer().isPlaying();
        }
        return false;
    }

    /**
     * 如果已经设置播放器{@link #createPlayer()},并且数据源已经设置{@link #setMediaSourceFromUri(Uri)},播放没有完成,那么将暂停播放,可以通过{@link #play()}恢复播放
     */
    public void pause() {

        Player player = playerView.getPlayer();
        if ( player == null ) {
            return;
        }

        int playbackState = player.getPlaybackState();
        if ( playbackState == Player.STATE_IDLE ) {
            return;
        }

        if ( playbackState == Player.STATE_ENDED ) {
            return;
        }

        player.setPlayWhenReady( false );
    }

    /**
     * 如果已经设置播放器{@link #createPlayer()},并且数据源已经设置{@link #setMediaSourceFromUri(Uri)},使用该方法可以停止,停止后
     * 播放器处于闲置状态{@link Player#STATE_IDLE},需要设置数据源之后才能播放{@link #play()}
     */
    public void stop() {

        Player player = playerView.getPlayer();
        if ( player == null ) {
            return;
        }

        int playbackState = player.getPlaybackState();
        if ( playbackState == Player.STATE_IDLE ) {
            return;
        }

        if ( playbackState == Player.STATE_ENDED ) {
            return;
        }

        player.stop();
    }

    /**
     * @return 获取播放器
     */
    @Nullable
    public Player getPlayer() {

        return playerView.getPlayer();
    }

    /**
     * @param useController 是否显示控制器
     */
    public void setUseController( boolean useController ) {

        playerView.setUseController( useController );
    }

    /**
     * 设置一个view作为播放按钮,播放时隐藏,暂停后显示,播放完成后也显示,点击可以播放数据
     */
    public void setViewAsPlayButton( View view ) {

        Player player = playerView.getPlayer();
        if ( player == null ) {
            return;
        }
        player.addListener( new Listener() {
            @Override
            public void onPlaybackStateChanged( @State int playbackState ) {

                if ( playbackState == Player.STATE_READY ) {
                    // 视频开始播放
                    view.setVisibility( View.GONE );
                } else if ( playbackState == Player.STATE_ENDED ) {
                    // 视频播放完成
                    view.setVisibility( View.VISIBLE );
                }
            }
        } );

        view.setOnClickListener( new OnClickListener() {
            @Override
            public void onClick( View v ) {

                if ( player.isPlaying() ) {
                    player.setPlayWhenReady( false );
                    view.setVisibility( View.VISIBLE );
                    return;
                }

                int playbackState = player.getPlaybackState();
                if ( playbackState == Player.STATE_ENDED ) {
                    player.seekTo( 0 );
                }
                player.setPlayWhenReady( true );
                view.setVisibility( View.GONE );
            }
        } );
    }
}
